package algo3.grupo3.modelo;


public class Casilla implements DependienteDelTiempo {

	private Casilla casillaDerecha,casillaIzquierda,casillaSuperior,casillaInferior;
	private ObjetoAnimado ocupante = null;
	private ObjetoAnimado ocupanteSuperpuesto= null;
	/*ocupanteSuperpuesto fue diseniado escencialmente para aquellos obstaculos que ocupen espacio como bombas
	 * o bloques. */
	private Articulo articulo = null;
	private boolean casillaEstaExplotando = false;
	
	private int posicionX , posicionY;/*aniandi que una casilla tenga una coordenada */
	
	
	public Casilla(Casilla cde, Casilla ciz, Casilla csu, Casilla cin){
		
		this.casillaDerecha = cde;
		if (cde != null){
			cde.setearCasillaIzquierda(this);
		}
		
		this.casillaInferior = cin;
		if(cin != null){
			cin.setearCasillaSuperior(this);
		}
		
		this.casillaSuperior = csu;
		if(csu != null){
			csu.setearCasillaInferior(this);
		}
		
		this.casillaIzquierda = ciz;
		if(ciz != null){
			ciz.setearCasillaDerecha(this);
		}
		
		this.vaciarCasilla();
		
	}//fin de constructor
	
	public Casilla(Casilla cde, Casilla ciz, Casilla csu, Casilla cin, ObjetoAnimado oa){
		
		this(cde, ciz, csu, cin);
		this.ocupar(oa);
		
	}//fin de constructor
	
	public Casilla(ObjetoAnimado oa){
		this(null, null, null, null);
		this.ocupar(oa);
	}//fin de constructor
	
	public Casilla(Articulo a){
		this(null, null, null, null);
		this.articulo= a;
	}//fin de constructor
	
	public Casilla(){
		this(null, null, null, null);
		this.vaciarCasilla();
	}//fin de constructor
	
	
	/*FIN DE CONSTRUCTORES----------------------------------------------------------- */
	
	
	public void vaciarCasilla(){
		this.removerArticulo();
		this.removerOcupantes();
	}//fin de vaciarCasilla
	
	public void removerOcupante(){
		if(this.ocupante== null)
			return;
		this.ocupante=null;
	}//fin de removerOcupante
	
	public void removerOcupanteSuperpuesto(){
		if(this.ocupanteSuperpuesto== null)
			return;
		this.ocupanteSuperpuesto= null;
	}//fin de reomverOcupanteSuperpuesto
	/*removerOcupante*** no deben invocar a destruir de ObjetoAnimado */
	
	public void removerOcupantes(){
		this.removerOcupante();
		this.removerOcupanteSuperpuesto();
	}//fin de removerOcupantes
	
	public void removerArticulo(){
		this.articulo = null;
	}//fin de removerArticulo
	
	public void ocupar( ObjetoAnimado oa )  {		
		this.ocupante = oa;
		this.ocupante.setPosicion(this);
	}//fin de objetoOcupaCasilla
	
	public void compartir( ObjetoAnimado oa ){
		this.ocupanteSuperpuesto= oa;
		this.ocupanteSuperpuesto.setPosicion(this);
	}//fin de compartirCasilla
	
	public void dejarArticulo( Articulo a ){
		
		this.articulo = a;
		
	}//fin de articuloOcupaCasilla
	
	
	public boolean hayUnOcupanteSuperpuesto(){
		return (this.ocupanteSuperpuesto != null);
	}//fin de hayUnOcupanteSuperpuesto
	
	
	/*indica si en la casilla hay un ocupante */
	public boolean estaOcupada(){		
		return (this.ocupante!= null || this.ocupanteSuperpuesto!= null);
	}//fin de casillaEstaVacia
	
	public boolean estaLlena(){
		return (this.ocupante!= null && this.ocupanteSuperpuesto != null);
	}//fin de estaLlena
	
	public boolean tieneOcupantePrincipal(){
		return (this.ocupante!=null);
	}

	
	/*retorna true en caso que la casilla no tenga ocupantes ni articulos dentro */
	public boolean estaVacia(){
		return( this.ocupante==null && this.ocupanteSuperpuesto==null && !this.tieneArticulo() );
	}//fin de estaVacia
	
	/*indica si en la casilla se encuentra un articulo */
	public boolean tieneArticulo(){
		return (this.articulo!= null);
	}//fin de tieneArticulo	
	
	
	public Casilla obtenerCasillaDerecha(){		
		return this.casillaDerecha;		
	}//fin de obtenerCasillaDerecha
	
	public Casilla obtenerCasillaIzquierda(){		
		return this.casillaIzquierda;		
	}//fin de obtenerCasillaIzquierda
	
	public Casilla obtenerCasillaSuperior(){
		return this.casillaSuperior;
	}//fin de obtenerCasillaSuperior
	
	public Casilla obtenerCasillaInferior(){
		return this.casillaInferior;
	}//fin de obtenerCasillaInferior
	
	public void setearCasillaDerecha(Casilla cd){
		this.casillaDerecha= cd;
	}//fin de setearCasillaDerecha
	
	public void setearCasillaIzquierda(Casilla ci){
		this.casillaIzquierda= ci;
	}//fin de setearCasillaIZquierda
	
	public void setearCasillaSuperior(Casilla cs){
		this.casillaSuperior= cs;
	}//fin de setearCasillaSuperior
	
	public void setearCasillaInferior( Casilla cin ){
		this.casillaInferior= cin;
	}//fin de setearCasillaInferior
	
	
	public boolean casillaEstaExplotando(){
		return this.casillaEstaExplotando;
	}//fin de casillaEstaExplotando
	
	public void expandirExplosion(int poderExplosion){
		
		if(poderExplosion <= 0 || !this.estaOcupada())
			return;
		
		if(this.ocupante!=null){
			ocupante.lastimar(poderExplosion);
			if(!this.ocupante.sigueActivo())
				this.removerOcupante();
		}
		
		if(this.ocupanteSuperpuesto!= null){
			ocupanteSuperpuesto.lastimar(poderExplosion);
			if(!this.ocupanteSuperpuesto.sigueActivo())
				this.removerOcupanteSuperpuesto();
		}
		
			
		this.casillaEstaExplotando= true;
		
	}//fin de casillaExplota
	
	public void explosionTermina(){
		
		this.casillaEstaExplotando = false;
		
	}//fin de explosionCasillaTermina
	
	public ObjetoAnimado obtenerOcupante(){
		return this.ocupante;
	}//fin de obtenerOcupante
	
	public ObjetoAnimado obtenerOcupanteSuperpuesto(){
		return this.ocupanteSuperpuesto;
	}
	
	public Articulo obtenerArticulo(){
		return this.articulo;
	}
	
	public boolean ocupanteEsAtravesable(){
		if(this.ocupante == null)
			return true;
		return this.ocupante.esAtravesable();
	}//fin de ocupanteEsAtravesable
	
	public boolean ocupanteSuperpuestoEsAtravesable(){
		if(this.ocupanteSuperpuesto==null)
			return true;
		return this.ocupanteSuperpuesto.esAtravesable();
	}
	
	public boolean ocupantesSonAtravesables(){
		if(this.ocupanteEsAtravesable() && this.ocupanteSuperpuestoEsAtravesable())
			return true;
		return false;
	}
	
	public void setearPosicionX(int posX){
		if(posX >= 0)
			this.posicionX= posX;
	}//fin de setearPosicionX
	
	public void setearPosicionY(int posY){
		if(posY >= 0)
			this.posicionY= posY;
	}//fin de setearPosicionY
	
	public int[] obtenerPosicion(){
		int posicion[]= new int[2];
		posicion[0]= this.posicionX;
		posicion[1]= this.posicionY;
		return posicion;
	}//fin de obtenerPosicion

	@Override
	public void actualizarEstado(double tiempoCiclo) {
		if(this.ocupante!=null)
			this.ocupante.actualizarEstado(tiempoCiclo);
		if(this.ocupanteSuperpuesto!= null)
			this.ocupanteSuperpuesto.actualizarEstado(tiempoCiclo);
	}//fin de actualizarEstado
	
	
	
}//fin de Casilla
